/*
 * Copyright (C) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup OH_Camera
 * @{
 *
 * @brief 为相机模块提供C接口的定义。
 *
 * @syscap SystemCapability.Multimedia.Camera.Core
 *
 * @since 11
 * @version 1.0
 */

/**
 * @file camera_manager.h
 *
 * @brief 声明相机管理器的概念。
 *
 * @library libohcamera.so
 * @syscap SystemCapability.Multimedia.Camera.Core
 * @since 11
 * @version 1.0
 */

#ifndef NATIVE_INCLUDE_CAMERA_CAMERA_MANAGER_H
#define NATIVE_INCLUDE_CAMERA_CAMERA_MANAGER_H

#include <stdint.h>
#include <stdio.h>
#include "camera.h"
#include "camera_input.h"
#include "capture_session.h"
#include "preview_output.h"
#include "video_output.h"
#include "photo_output.h"
#include "metadata_output.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 在{@link CameraManager_Callbacks}中被调用的相机管理器状态回调。
 *
 * @param cameraManager 传递回调的{@link Camera_Manager}。
 * @param status 每个相机设备的{@link Camera_StatusInfo}。
 * @since 11
 */
typedef void (*OH_CameraManager_StatusCallback)(Camera_Manager* cameraManager, Camera_StatusInfo* status);

/**
 * @brief 手电筒状态变化回调。
 *
 * @param cameraManager 传递回调的{@link Camera_Manager}。
 * @param status 手电筒的状态{@link Camera_TorchStatusInfo}。
 * @since 12
 */
typedef void (*OH_CameraManager_TorchStatusCallback)(Camera_Manager* cameraManager, Camera_TorchStatusInfo* status);

/**
 * @brief 相机设备状态的回调。
 *
 * @see OH_CameraManager_RegisterCallback
 * @since 11
 * @version 1.0
 */
typedef struct CameraManager_Callbacks {
    /**
     * 相机状态更改事件。
     */
    OH_CameraManager_StatusCallback onCameraStatus;
} CameraManager_Callbacks;

/**
 * @brief 注册相机状态更改事件回调。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param callback 要注册的{@link CameraManager_Callbacks}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_RegisterCallback(Camera_Manager* cameraManager, CameraManager_Callbacks* callback);

/**
 * @brief 注销摄像机状态更改事件回调。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param callback 要注销的{@link CameraManager_Callbacks}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_UnregisterCallback(Camera_Manager* cameraManager, CameraManager_Callbacks* callback);

/**
 * @brief 注册手电筒状态变更事件回调。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param torchStatusCallback 要注册的{@link OH_CameraManager_TorchStatusCallback}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_RegisterTorchStatusCallback(Camera_Manager* cameraManager,
    OH_CameraManager_TorchStatusCallback torchStatusCallback);

/**
 * @brief 注销手电筒状态变更事件回调。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param torchStatusCallback 要注销的{@link OH_CameraManager_TorchStatusCallback}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_UnregisterTorchStatusCallback(Camera_Manager* cameraManager,
    OH_CameraManager_TorchStatusCallback torchStatusCallback);

/**
 * @brief 获取支持相机的描述。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param cameras 如果方法调用成功，则将记录支持的{@link Camera_Device}列表。
 * @param size 如果方法调用成功，则将记录支持的{@link Camera_Device}列表的大小。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_GetSupportedCameras(Camera_Manager* cameraManager,
    Camera_Device** cameras, uint32_t* size);

/**
 * @brief 删除支持的相机。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param cameras 要删除的{@link Camera_Device}列表。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_DeleteSupportedCameras(Camera_Manager* cameraManager,
    Camera_Device* cameras, uint32_t size);

/**
 * @brief 查询指定相机在指定模式下支持的输出能力。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param cameras 要查询的{@link Camera_Device}。
 * @param cameraOutputCapability 如果方法调用成功，则将记录支持的{@link Camera_OutputCapability}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_GetSupportedCameraOutputCapability(Camera_Manager* cameraManager,
    const Camera_Device* camera, Camera_OutputCapability** cameraOutputCapability);

/**
 * @brief 查询指定相机在指定模式下支持的输出能力。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param camera 被查询的{@link Camera_Device}。
 * @param sceneMode 指定相机模式{@link Camera_SceneMode}。
 * @param cameraOutputCapability 如果方法调用成功，则将记录支持的{@link Camera_OutputCapability}列表。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_GetSupportedCameraOutputCapabilityWithSceneMode(Camera_Manager* cameraManager,
    const Camera_Device* camera, Camera_SceneMode sceneMode, Camera_OutputCapability** cameraOutputCapability);

/**
 * @brief 删除支持的输出功能。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param cameraOutputCapability 要删除的{@link Camera_OutputCapability}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_DeleteSupportedCameraOutputCapability(Camera_Manager* cameraManager,
    Camera_OutputCapability* cameraOutputCapability);

/**
 * @brief 确定相机是否静音。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param isCameraMuted 如果方法调用成功，将判断相机是否静音。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_IsCameraMuted(Camera_Manager* cameraManager, bool* isCameraMuted);

/**
 * @brief 创建捕获会话实例。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param captureSession 如果方法调用成功，则将创建{@link Camera_CaptureSession}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_CreateCaptureSession(Camera_Manager* cameraManager,
    Camera_CaptureSession** captureSession);

/**
 * @brief 创建相机输入实例。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param camera 用于创建{@link Camera_Input}的{@link Camera_Device}。
 * @param cameraInput 如果方法调用成功，将创建{@link Camera_Input}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @permission ohos.permission.CAMERA
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_CreateCameraInput(Camera_Manager* cameraManager,
    const Camera_Device* camera, Camera_Input** cameraInput);

/**
 * @brief 创建具有位置和类型的相机输入实例
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param position 用于创建{@link Camera_Input}的{@link Camera_Position}。
 * @param type 用于创建{@link Camera_Input}的{@linkCamera_Type}。
 * @param cameraInput 如果方法调用成功，将创建{@link Camera_Input}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @permission ohos.permission.CAMERA
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_CreateCameraInput_WithPositionAndType(Camera_Manager* cameraManager,
    Camera_Position position, Camera_Type type, Camera_Input** cameraInput);

/**
 * @brief 创建预览输出实例。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param profile 用于创建{@link Camera_PreviewOutput}的{@link Camera_Profile}。
 * @param surfaceId 用于创建{@link Camera_PreviewOutput}的surfaceId。
 * @param previewOutput 如果方法调用成功，将创建{@link Camera_PreviewOutput}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_CreatePreviewOutput(Camera_Manager* cameraManager, const Camera_Profile* profile,
    const char* surfaceId, Camera_PreviewOutput** previewOutput);

/**
 * @brief 创建在预配置流中使用的预览输出实例。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param surfaceId 用于创建{@link Camera_PreviewOutput}的surfaceId。
 * @param previewOutput 如果方法调用成功，将创建{@link Camera_PreviewOutput}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_CreatePreviewOutputUsedInPreconfig(Camera_Manager* cameraManager,
    const char* surfaceId, Camera_PreviewOutput** previewOutput);

/**
 * @brief 创建一个拍照输出实例。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param profile 用于创建{@link Camera_PhotoOutput}的{@link Camera_Profile}。
 * @param surfaceId 用于创建{@link Camera_PhotoOutput}的surfaceId。
 * @param photoOutput 如果方法调用成功，将创建{@link Camera_PhotoOutput}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_CreatePhotoOutput(Camera_Manager* cameraManager, const Camera_Profile* profile,
    const char* surfaceId, Camera_PhotoOutput** photoOutput);

/**
 * @brief 创建在预配置流中使用的照片输出实例。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param surfaceId 用于创建{@link Camera_PhotoOutput}的surfaceId。
 * @param photoOutput 如果方法调用成功，将创建{@link Camera_PhotoOutput}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_CreatePhotoOutputUsedInPreconfig(Camera_Manager* cameraManager,
    const char* surfaceId, Camera_PhotoOutput** photoOutput);

/**
 * @brief 创建照片输出实例，调用此函数不需要surfaceId。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param profile 用于创建{@link Camera_PhotoOutput}的{@link Camera_Profile}。
 * @param photoOutput 如果方法调用成功，将创建{@link Camera_PhotoOutput}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_CreatePhotoOutputWithoutSurface(Camera_Manager *cameraManager,
    const Camera_Profile *profile, Camera_PhotoOutput **photoOutput);

/**
 * @brief 创建一个录像输出实例。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param profile 用于创建{@link Camera_VideoOutput}的{@link Camera_VideoProfile}。
 * @param surfaceId 用于创建{@link Camera_VideoOutput}的surfaceId。
 * @param videoOutput 如果方法调用成功，将创建{@link Camera_VideoOutput}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_CreateVideoOutput(Camera_Manager* cameraManager, const Camera_VideoProfile* profile,
    const char* surfaceId, Camera_VideoOutput** videoOutput);

/**
 * @brief 创建在预配置流中使用的视频输出实例。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param surfaceId 用于创建{@link Camera_VideoOutput}的surfaceId。
 * @param videoOutput 如果方法调用成功，将创建{@link Camera_VideoOutput}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_CreateVideoOutputUsedInPreconfig(Camera_Manager* cameraManager,
    const char* surfaceId, Camera_VideoOutput** videoOutput);

/**
 * @brief 创建元数据输出实例。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param profile 用于创建{@link Camera_MetadataOutput}的{@link Camera_MetadataObjectType}.
 * @param metadataOutput 如果方法调用成功，将创建{@link Camera_MetadataOutput}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 11
 */
Camera_ErrorCode OH_CameraManager_CreateMetadataOutput(Camera_Manager* cameraManager,
    const Camera_MetadataObjectType* profile, Camera_MetadataOutput** metadataOutput);

/**
 * @brief 获取特定摄影机支持的场景模式。
 *
 * @param camera 要查询的{@link Camera_Device}。
 * @param sceneModes 如果方法调用成功，则将记录支持的{@link Camera_SceneMode}列表。
 * @param size 如果方法调用成功，则将记录支持的{@link Camera_SceneMode}的列表大小。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_GetSupportedSceneModes(Camera_Device* camera,
    Camera_SceneMode** sceneModes, uint32_t* size);

/**
 * @brief 删除场景模式。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param sceneModes 要删除的{@link Camera_SceneMode}列表。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_DeleteSceneModes(Camera_Manager* cameraManager, Camera_SceneMode* sceneModes);

/**
 * @brief 检查设备是否支持手电筒。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param isTorchSupported 设备是否支持手电筒。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_IsTorchSupported(Camera_Manager* cameraManager,
    bool* isTorchSupported);

/**
 * @brief 检查设备是否支持指定的手电筒模式。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param torchMode 要检查的{@link Camera_TorchMode}。
 * @param isTorchSupported 设备是否支持指定的手电筒模式。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_IsTorchSupportedByTorchMode(Camera_Manager* cameraManager,
    Camera_TorchMode torchMode, bool* isTorchSupported);

/**
 * @brief 设置相机手电筒模式。
 *
 * @param cameraManager 相机管理器实例{@link Camera_Manager}。
 * @param torchMode 要设置的{@link Camera_TorchMode}。
 * @return {@link#CAMERA_OK}如果方法调用成功。
 *         {@link#CAMERA_INVALID_ARGUMENT}如果参数丢失或参数类型不正确。
 *         {@link#CAMERA_SERVICE_FATAL_ERROR}如果相机服务出现致命错误。
 * @since 12
 */
Camera_ErrorCode OH_CameraManager_SetTorchMode(Camera_Manager* cameraManager,
    Camera_TorchMode torchMode);

#ifdef __cplusplus
}
#endif

#endif // NATIVE_INCLUDE_CAMERA_CAMERA_MANAGER_H
/** @} */